{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b11ef99e-b811-4215-a1ee-aa161cf901f9",
   "metadata": {},
   "source": [
    "# Widget List\n",
    "This is a translation from IPython's [Widget List](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html) to IHaskell"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "db4f655b-d163-4dd5-a8cf-8a5cf0fbca48",
   "metadata": {},
   "outputs": [],
   "source": [
    "{-# LANGUAGE OverloadedStrings #-}\n",
    "import Data.Text\n",
    "import IHaskell.Display.Widgets as W\n",
    "import IHaskell.Display.Widgets.Layout as L\n",
    "import Data.Proxy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5c589b6-889d-4147-8381-a261f6dbbe0b",
   "metadata": {},
   "source": [
    "## Numeric widgets\n",
    "These are widgets designed to display numeric values. You can display both integers and floats, with or wihtout bounding.\n",
    "\n",
    "These widgets usually share the same naming scheme, so you can find the `Float`/`Int` counterpart replacing `Int` with `Float` or viceversa."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b582ed8f-8221-4d9d-886e-bafd13574837",
   "metadata": {},
   "source": [
    "### IntSlider\n",
    "- Initially the slider is displayed with `IntValue`. You can define the lower/upper bounds with `MinInt` and `MaxInt`, the value increments/decrements according to `StepInt`. If `StepInt` is `Nothing`, you let the frontend decide.\n",
    "- You can specify a label in the `Description` field\n",
    "- The slider orientation is either `HorizontalOrientation` or `VerticalOrientation`\n",
    "- `ReadOut` chooses whether to display the value next to the slider, and `ReadOutFormat` specifies the format in a similar way to the format used by `printf`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d2954629-2d81-4817-b366-bca2e62d8d6e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "79d4d88b-45c4-408d-840b-fc2242463b1e",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "intSlider <- mkIntSlider\n",
    "setField @IntValue intSlider 7\n",
    "setField @MinInt intSlider 0\n",
    "setField @MaxInt intSlider 100\n",
    "setField @StepInt intSlider $ Just 1\n",
    "setField @Description intSlider \"Test: \"\n",
    "setField @Disabled intSlider False\n",
    "setField @ContinuousUpdate intSlider False\n",
    "setField @Orientation intSlider HorizontalOrientation\n",
    "setField @ReadOut intSlider True\n",
    "setField @ReadOutFormat intSlider \"d\"\n",
    "intSlider"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fd35980-f787-459c-9204-83a7f48973b0",
   "metadata": {},
   "source": [
    "### FloatSlider\n",
    "An example of a float slider displayed vertically"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6a96cd33-8007-42b1-b618-0b96bb8bbe31",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "468ae5e9-1c09-4d57-b3b7-c4f0016f8c85",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "floatSlider <- mkFloatSlider\n",
    "setField @FloatValue floatSlider 7.5\n",
    "setField @MinFloat floatSlider 0.0\n",
    "setField @MaxFloat floatSlider 10.0\n",
    "setField @StepFloat floatSlider $ Just 0.1\n",
    "setField @Description floatSlider \"Test float: \"\n",
    "setField @Disabled floatSlider False\n",
    "setField @ContinuousUpdate floatSlider False\n",
    "setField @Orientation floatSlider VerticalOrientation\n",
    "setField @ReadOut floatSlider True\n",
    "setField @ReadOutFormat floatSlider \".1f\"\n",
    "floatSlider"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a040a09-5d39-4c8e-a1ae-d732e390fbb2",
   "metadata": {},
   "source": [
    "### FloatLogSlider\n",
    "Like a normal slider, but every step multiplies by a quantity, creating an exponential value (or a log scale). `MinFloat` and `MaxFloat` refer to the minimum and maximum **exponents** of the `BaseFloat`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "f09bec94-8bb3-45ce-99fe-a3bcb48852ec",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "45f9a996-cf10-4507-9448-0182819c720c",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "floatLogSlider <- mkFloatLogSlider\n",
    "setField @FloatValue floatLogSlider 10\n",
    "setField @BaseFloat floatLogSlider 10\n",
    "setField @MinFloat floatLogSlider (-10)\n",
    "setField @MaxFloat floatLogSlider 10\n",
    "setField @StepFloat floatLogSlider $ Just 0.2\n",
    "setField @Description floatLogSlider \"A log slider\"\n",
    "floatLogSlider"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ee6499d-c970-4ce1-aa19-45450a7b614b",
   "metadata": {},
   "source": [
    "### IntRangeSlider\n",
    "Lets you choose a range of two values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "7ba73761-5487-44c7-a8c2-5d315a33fa6a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "250208f4-c592-4b9f-85a1-fc5fd301d6f6",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "intRangeSlider <- mkIntRangeSlider\n",
    "setField @IntPairValue intRangeSlider (5,7)\n",
    "setField @MinInt intRangeSlider 0\n",
    "setField @MaxInt intRangeSlider 10\n",
    "setField @StepInt intRangeSlider $ Just 1\n",
    "setField @Disabled intRangeSlider False\n",
    "setField @ContinuousUpdate intRangeSlider False\n",
    "setField @Orientation intRangeSlider HorizontalOrientation\n",
    "setField @ReadOut intRangeSlider True\n",
    "setField @ReadOutFormat intRangeSlider \"d\"\n",
    "intRangeSlider"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ace46345-d799-40ba-9964-eb97e44d55a2",
   "metadata": {},
   "source": [
    "### FloatRangeSlider"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "1098100a-c2f8-4883-a8ce-3a03560447bb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8649f114-34ec-4166-a9e3-77a084ddcb1d",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "floatRangeSlider <- mkFloatRangeSlider\n",
    "setField @FloatPairValue floatRangeSlider (5.0,7.5)\n",
    "setField @MinFloat floatRangeSlider 0\n",
    "setField @MaxFloat floatRangeSlider 10\n",
    "setField @StepFloat floatRangeSlider $ Just 0.1\n",
    "setField @Disabled floatRangeSlider False\n",
    "setField @ContinuousUpdate floatRangeSlider False\n",
    "setField @Orientation floatRangeSlider HorizontalOrientation\n",
    "setField @ReadOut floatRangeSlider True\n",
    "setField @ReadOutFormat floatRangeSlider \".1f\"\n",
    "floatRangeSlider"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "11b9018d-aff6-414d-89c6-a61026ea084a",
   "metadata": {},
   "source": [
    "### IntProgress\n",
    "- `BarStyle` can be one of: \n",
    "    - `DefaultBar`\n",
    "    - `SuccessBar`\n",
    "    - `InfoBar`\n",
    "    - `WarningBar`\n",
    "    - `DangerBar`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "1f47e516-a0df-4365-9093-a9649adbcfbb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "945fbcd1-9195-4173-ba00-8661b18fa2df",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "intProgress <- mkIntProgress\n",
    "setField @IntValue intProgress 7\n",
    "setField @MinInt intProgress 0\n",
    "setField @MaxInt intProgress 10\n",
    "setField @Description intProgress \"Now loading\"\n",
    "setField @BarStyle intProgress InfoBar\n",
    "intProgress"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "eef18bbb-c96b-47f1-bdab-a12b0c66b865",
   "metadata": {},
   "outputs": [],
   "source": [
    "s <- mkProgressStyle\n",
    "setField @BarColor s $ Just \"#ffff00\"\n",
    "setField @Style intProgress (StyleWidget s)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b47fbb20-5c0a-4124-84fd-d06f2a10b635",
   "metadata": {},
   "source": [
    "If a numerical text box imposes some kind of limit on the input (range, non-float, etc), that restriction is checked when the user presses enter or changes focus\n",
    "### BoundedIntText"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "3c09cc52-5187-4698-96f6-1c12729a7cfe",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e3c59262-0466-41bb-9616-38906896971f",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "boundedIntText <- mkBoundedIntText\n",
    "setField @IntValue boundedIntText 7\n",
    "setField @MinInt boundedIntText 0\n",
    "setField @MaxInt boundedIntText 10\n",
    "setField @StepInt boundedIntText $ Just 1\n",
    "setField @Description boundedIntText \"Text: \"\n",
    "setField @Disabled boundedIntText False\n",
    "boundedIntText"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83bf9e9c-4d9b-4682-a94d-018e765bd7a8",
   "metadata": {},
   "source": [
    "### BoundedFloatText"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "652ece64-05e4-484b-af80-4971ea5fa27c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "2ba6739e-d35d-4d0d-8492-3cdfc6113c4b",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "boundedFloatText <- mkBoundedFloatText\n",
    "setField @FloatValue boundedFloatText 7.5\n",
    "setField @MinFloat boundedFloatText 0.0\n",
    "setField @MaxFloat boundedFloatText 10.0\n",
    "setField @StepFloat boundedFloatText (Just 0.1)\n",
    "setField @Description boundedFloatText \"Text: \"\n",
    "setField @Disabled boundedFloatText False\n",
    "boundedFloatText"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e1b04bd-9dfa-44f4-9d68-8b0617fa797c",
   "metadata": {},
   "source": [
    "### IntText"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "9d306ca8-6abb-4644-98d8-38a11d4b5bad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "4ba3c3f7-05ae-4e82-87e8-264d08d49e92",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "intText <- mkIntText\n",
    "setField @IntValue intText 7\n",
    "setField @Description intText \"Any:\"\n",
    "setField @Disabled intText False\n",
    "intText"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b55e67cd-8e88-4ee2-b9cf-bd31b9d7ea26",
   "metadata": {},
   "source": [
    "### FloatText"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "811aab8a-c6ee-41d6-b9a9-99a4d0924a93",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "fa20a112-58c1-4f3e-9e7a-ca5dfd470095",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "floatText <- mkFloatText\n",
    "setField @FloatValue floatText 7.5\n",
    "setField @Description floatText \"Any:\"\n",
    "setField @Disabled floatText False\n",
    "floatText"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ba33cd5-b40c-4f47-ae0f-935c6b2471f5",
   "metadata": {},
   "source": [
    "https://twitter.com/Jose6o/status/1425485091824939012/photo/1## Boolean Widgets\n",
    "The following three widgets display a boolean value\n",
    "\n",
    "### ToggleButton"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "7be1e91b-f28e-4be3-83cb-ac0954a87db8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "0ba3caad-97b8-4287-bfd8-676c89410c7d",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "toggleButton <- mkToggleButton\n",
    "setField @BoolValue toggleButton False\n",
    "setField @Description toggleButton \"Click me\"\n",
    "setField @Disabled toggleButton False\n",
    "-- DefaultButton | PrimaryButton | SuccessButton | INfoButton | WarningButton | DangerButton\n",
    "setField @ButtonStyleField toggleButton DefaultButton\n",
    "setField @Tooltip toggleButton $ Just \"Description\"\n",
    "setField @Icon toggleButton \"check\"\n",
    "toggleButton"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1e9442f-52a9-4bb9-b6ae-1e593ae1f451",
   "metadata": {},
   "source": [
    "### Checkbox"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "0514c055-060d-493d-aa91-55dc00cb0d5f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "60105b27-2524-4416-9f3b-23ed1cf7dcd1",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "checkBox <- mkCheckBox\n",
    "setField @BoolValue checkBox False\n",
    "setField @Description checkBox \"Check me out!\"\n",
    "setField @Disabled checkBox False\n",
    "setField @Indent checkBox False\n",
    "checkBox"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fcedc017-cab4-4ccf-a097-8cce0d049e85",
   "metadata": {},
   "source": [
    "### Valid\n",
    "It provides a read-only indicator."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "606594cb-08a3-41a2-b060-9d2d0ef3f588",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "ddc56e90-8284-44e6-8d05-2e8d738b53df",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "valid <- mkValid\n",
    "setField @BoolValue valid False\n",
    "setField @Description valid \"Valid?\"\n",
    "valid"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c1111c3-3470-44f4-8782-c68093e54ed7",
   "metadata": {},
   "source": [
    "## Selection widgets\n",
    "There are several widgets that can be used to display single selection lists, and two that can be used to select multiple values. All inherit from the same base class. You can specify the **enumeration of selectable options** by passing a list of options labels.\n",
    "\n",
    "The selected index is specified with the field `OptionalIndex` in case it can be `Nothing` and `Index` if it's not a Maybe.\n",
    "\n",
    "### Dropdown"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "9472cea4-69f1-409c-8244-1e79a5f56050",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7a48fe8f-a7c9-4400-bd23-1a849041a045",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dropdown <- mkDropdown\n",
    "setField @OptionsLabels dropdown [\"1\", \"2\", \"3\"]\n",
    "setField @OptionalIndex dropdown $ Just 2\n",
    "setField @Description dropdown \"Number:\"\n",
    "setField @Disabled dropdown False\n",
    "dropdown"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a28e4444-a57e-47da-ad6b-0156754c2e87",
   "metadata": {},
   "source": [
    "### RadioButtons"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "013b11dd-f193-4011-9539-ce177c2df0e0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b5477e5d-b3ed-48a6-9c55-75e569d0ce9c",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "radioButtons <- mkRadioButtons\n",
    "setField @OptionsLabels radioButtons [\"pepperoni\", \"pineapple\", \"anchovies\"]\n",
    "setField @OptionalIndex radioButtons Nothing\n",
    "setField @Description radioButtons \"Topping:\"\n",
    "setField @Disabled radioButtons False\n",
    "radioButtons"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4850f444-e7ae-49df-9655-d528efbe4de1",
   "metadata": {},
   "source": [
    "Here is an exemple with dynamic layout and very long labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "abd06526-4838-4d2e-b191-136fad9e10f5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "bd519145-a4dc-440f-bccf-6a5465b75fbd",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "radioButtons' <- mkRadioButtons\n",
    "setField @OptionsLabels radioButtons' [\n",
    "    \"pepperoni\",\n",
    "    \"pineapple\",\n",
    "    \"anchovies\",\n",
    "    \"Spam, sausage, Spam, Spam, Spam, bacon, Spam, tomato and Spam\"\n",
    "    ]\n",
    "label <- mkLabel\n",
    "setField @StringValue label \"Pizza topping with a very long label\"\n",
    "\n",
    "layout <- mkLayout\n",
    "setField @L.Width layout $ Just \"max-content\"\n",
    "\n",
    "box <- mkBox\n",
    "setField @Children box [ChildWidget label, ChildWidget radioButtons']\n",
    "setField @W.Layout box layout\n",
    "box"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43f0cf55-6a16-4df8-bc41-e872cd580ed6",
   "metadata": {},
   "source": [
    "### Select"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "bcd0e446-cb09-49a9-b41c-08cf81094bfc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "3f14b524-41af-4e19-961f-1461ef77cbc9",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "select <- mkSelect\n",
    "setField @OptionsLabels select [\"Linux\", \"Windows\", \"OSX\"]\n",
    "setField @OptionalIndex select $ Just 0\n",
    "setField @Description select \"OS:\"\n",
    "setField @Disabled select False\n",
    "select"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "925a3f0a-e244-44dc-a132-00d020409461",
   "metadata": {},
   "source": [
    "### SelectionSlider"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "4a59fe64-0b50-49d8-897b-b96a56bc5a43",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "9939d223-0b38-416a-9eb3-68ccbb0e7ae6",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "selectionSlider <- mkSelectionSlider\n",
    "setField @OptionsLabels selectionSlider [\"Scrambled\", \"Sunny side up\", \"Poached\", \"Over easy\"]\n",
    "setField @Index selectionSlider 1\n",
    "setField @Description selectionSlider \"I like my eggs...\"\n",
    "setField @Disabled selectionSlider False\n",
    "setField @ContinuousUpdate selectionSlider False\n",
    "setField @Orientation selectionSlider HorizontalOrientation\n",
    "setField @ReadOut selectionSlider True\n",
    "selectionSlider"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90248741-f933-4232-a57f-facd527183d3",
   "metadata": {},
   "source": [
    "### SelectionRangeSlider"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d8fa0893-4614-4f28-94f6-b5504a063a42",
   "metadata": {},
   "outputs": [],
   "source": [
    "selectionRangeSlider <- mkSelectionRangeSlider\n",
    "setField @OptionsLabels selectionRangeSlider [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"]\n",
    "setField @Indices selectionRangeSlider [0, 4]\n",
    "setField @Description selectionRangeSlider \"When is the shop open?\"\n",
    "setField @Disabled selectionRangeSlider False\n",
    "selectionRangeSlider\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3fef32ea-011f-4d3c-a98e-fc25692dbe41",
   "metadata": {},
   "source": [
    "### ToggleButtons"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "0423d92a-3d9b-4f82-aeed-c869617817b3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "acefe3fb-800c-4f67-aad1-63928afb9923",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "toggleButtons <- mkToggleButtons\n",
    "setField @OptionsLabels toggleButtons [\"Slow\", \"Regular\", \"Fast\"]\n",
    "setField @Description toggleButtons \"Speed:\"\n",
    "setField @Disabled toggleButtons False\n",
    "setField @ButtonStyleField toggleButtons DefaultButton\n",
    "setField @Tooltips toggleButtons [\"Description of slow\", \"Description of regular\", \"Description of fast\"]\n",
    "toggleButtons"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "121404fa-3461-448a-a782-14a41e467863",
   "metadata": {},
   "source": [
    "### SelectMultiple\n",
    "Multiple values can be selected with `shift` and/or `ctrl` (or `command` with OSX) pressed and mouse click or arrow keys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "8332e274-bb0d-4be2-b9b4-a08c633f6a4b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d1a1d8fd-dc05-4de5-817a-c56112df19b9",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "selectMultiple <- mkSelectMultiple\n",
    "setField @OptionsLabels selectMultiple [\"Apples\", \"Oranges\", \"Pears\"]\n",
    "setField @Indices selectMultiple [1]\n",
    "setField @Description selectMultiple \"Fruits\"\n",
    "setField @Disabled selectMultiple False\n",
    "selectMultiple"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f571f5a5-a320-466f-a228-54d3ebb2d141",
   "metadata": {},
   "source": [
    "## String widgets\n",
    "There are multiple widgets that can be used to display a string value. The `Text`, `TextArea`\n",
    "and `Combobox` widgets accept input. The `HTML` and `HTMLMath` display the received string\n",
    "as HTML. The `Label` widget can be used to construct a custom control label, but it doesn't display\n",
    "input.\n",
    "\n",
    "### Text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "ce3ba3b3-cfea-41f8-ab61-a58b7db1d322",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "188228cc-1ed5-4290-a8db-0e5f958bdf4e",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "text <- mkText\n",
    "setField @StringValue text \"Hello World!\"\n",
    "setField @Placeholder text \"Type something\"\n",
    "setField @Description text \"String:\"\n",
    "setField @Disabled text False\n",
    "text"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fbd9d92-8822-4512-907f-4e0d39f7b726",
   "metadata": {},
   "source": [
    "### Textarea"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "0528b6ca-caac-4895-a071-6bb2d3a1838d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e216aeb9-ce61-4766-a2df-09d86a584085",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "textarea <- mkTextArea\n",
    "setField @StringValue textarea \"Hello World!\"\n",
    "setField @Placeholder textarea \"Type something\"\n",
    "setField @Description textarea \"Long string:\"\n",
    "setField @Disabled textarea False\n",
    "textarea"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f54b8f3-b24e-4a06-b222-64ab6bd818e0",
   "metadata": {},
   "source": [
    "### Combobox"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "6872c8b4-59e9-4eb6-9d32-9526f20940b2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "bb2d88f5-880c-4aed-9fa4-8f0c0cf60865",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "combobox <- mkCombobox\n",
    "setField @Placeholder combobox \"Choose Someone\"\n",
    "setField @Options combobox [\"Paul\", \"John\", \"George\", \"Ringo\"]\n",
    "setField @Description combobox \"Combobox:\"\n",
    "setField @EnsureOption combobox True\n",
    "setField @Disabled combobox False\n",
    "combobox"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6920d129-ea7d-40bb-bfa1-e0432fe8cc93",
   "metadata": {},
   "source": [
    "### Password\n",
    "\n",
    "The `Password` widget hides user input on the screen. Nevertheless, this widget is **not a secure way** to collect sensitive information **because**:\n",
    "- The contents are transmitted unencrypted\n",
    "- If you save the notebook, the contents are stored as plain text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "56554ed4-9003-4af0-a407-9ccc6dbb60c5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "266af757-8d05-49bc-a66f-f3278386b653",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "password <- mkPassword\n",
    "setField @StringValue password \"Password\"\n",
    "setField @Placeholder password \"Enter password\"\n",
    "setField @Description password \"Password:\"\n",
    "setField @Disabled password False\n",
    "password"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "666ad3b5-ae4a-4883-81ce-2e9c18daf3a1",
   "metadata": {},
   "source": [
    "### Label\n",
    "The `Label` widget is useful if you need to build a very customized description next to a control widget."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "b8c01e21-1438-47c5-ab9f-f70b08040f85",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "5ee8d7d6-9776-4a30-8fa8-942e18b0fdf5",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "label <- mkLabel\n",
    "setField @StringValue label \"The $m$ in $E=mc^2$:\"\n",
    "\n",
    "floatSlider <- mkFloatSlider\n",
    "\n",
    "hbox <- mkHBox\n",
    "setField @Children hbox [ChildWidget label, ChildWidget floatSlider]\n",
    "hbox"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a4107143-a81a-40f9-8f39-9da44ec1571d",
   "metadata": {},
   "source": [
    "### HTML"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "42d32123-22a5-4322-a8e5-efe1d2bc3deb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "716c5c49-8b7e-428e-8b95-d24484d3ab0f",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "html <- mkHTML\n",
    "setField @StringValue html \"Hello <b>World!</b>\"\n",
    "setField @Placeholder html \"Some HTML\"\n",
    "setField @Description html \"Some HTML\"\n",
    "html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92221dce-d246-4119-9c48-409477ad2743",
   "metadata": {},
   "source": [
    "### HTML Math\n",
    "Like HTML, but it also renders LaTeX math commands"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "7c277fa9-f8be-4f7b-bffe-26bc74298572",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d247a274-10d2-4036-9eec-4109eb7050a6",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "htmlMath <- mkHTMLMath\n",
    "-- Remember to escape the \\ with \\\\\n",
    "setField @StringValue htmlMath \"Some math and <i>HTML</i>: $x^2$ and $$\\\\frac{x+1}{x-1}$$\"\n",
    "setField @Placeholder htmlMath \"Some HTML\"\n",
    "setField @Description htmlMath \"Some HTML\"\n",
    "htmlMath"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8060d219-fadc-4647-bd7e-7af4f5f8d614",
   "metadata": {},
   "source": [
    "## Image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "01eff752-f657-4a11-ad1f-8daa4bff927e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "782c7f34-56a5-4308-abcf-42ef6236534c",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "image <- mkImage\n",
    "setField @BSValue image \"https://imgs.xkcd.com/comics/haskell.png\"\n",
    "-- PNG | SVG | JPG | IURL\n",
    "setField @ImageFormat image IURL\n",
    "image"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd20dcb7-5691-4b6e-b569-473624f9e6a1",
   "metadata": {},
   "source": [
    "## Button"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "bf84c8f3-75b2-468c-a4f3-53358bd3241f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ViewModule ::: Text\n",
       "ViewModuleVersion ::: Text\n",
       "ModelModule ::: Text\n",
       "ModelModuleVersion ::: Text\n",
       "ModelName ::: Text\n",
       "ViewName ::: Text\n",
       "DOMClasses ::: [Text]\n",
       "Tabbable ::: Maybe Bool\n",
       "Tooltip ::: Maybe Text\n",
       "Layout ::: IPythonWidget LayoutType\n",
       "DisplayHandler ::: IO ()\n",
       "Description ::: Text\n",
       "DescriptionAllowHtml ::: Maybe Bool\n",
       "Style ::: StyleWidget\n",
       "Disabled ::: Bool\n",
       "Icon ::: Text\n",
       "ButtonStyleField ::: ButtonStyleValue\n",
       "ClickHandler ::: IO ()"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c02b5802-3336-45ae-bc5f-308fec0ac4e0",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "button <- mkButton\n",
    "setField @Description button \"Click me\"\n",
    "setField @Disabled button False\n",
    "setField @ButtonStyleField button DefaultButton\n",
    "setField @Tooltip button (Just \"Click me\")\n",
    "setField @Icon button \"mouse\"\n",
    "properties button\n",
    "button"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37f880eb-2c98-446b-a38f-582b302b6fc3",
   "metadata": {},
   "source": [
    "The `Icon` attribute is used to define an icon; see the [fontawesome](https://fontawesome.com/v5.15/icons) page for available icons.\n",
    "\n",
    "You can set a callback function Setting the `ClickHandler ::: IO ()` attribute.\n",
    "\n",
    "## Output\n",
    "The `Output` widget is complicated and has many features. You can see detailed documentation in its dedicated Notebook.\n",
    "\n",
    "## Play (Animation) widget\n",
    "The `Play` widget is like an automated textbox, where someone is making click on increment every few miliseconds. Here you can see an example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "acdc051c-4c72-4fda-a29e-286ec8aa86f9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c2410530-615c-4acf-bfa2-3c810716c1e3",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7e72453c-84a7-49db-a17b-c821551a0816",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "4fc1ead3-53ce-43fd-b9c2-63103ce5a78f",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "play <- mkPlay\n",
    "setField @IntValue play 50\n",
    "setField @MinInt play 0\n",
    "setField @MaxInt play 100\n",
    "setField @StepInt play (Just 1)\n",
    "setField @Interval play 500\n",
    "setField @Description play \"Press play\"\n",
    "setField @Disabled play False\n",
    "\n",
    "slider <- mkIntSlider\n",
    "jslink (WidgetFieldPair play (Proxy @IntValue)) (WidgetFieldPair slider (Proxy @IntValue))\n",
    "\n",
    "play\n",
    "slider"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2db1169-1fb5-4140-81eb-0537230036bc",
   "metadata": {},
   "source": [
    "## Date Picker\n",
    "This widget only works with browser that support the HTML date input field (Chrome, Firefox and IE Edge, but not Safari)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "1572fa8f-992a-4bb2-976a-26c7db3599c8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "ae1acc56-058f-4b93-b766-4e5d51efb3b5",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "datePicker <- mkDatePicker\n",
    "setField @Description datePicker \"Pick a date\"\n",
    "setField @Disabled datePicker False\n",
    "datePicker"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b9fdf795-abb1-4220-8b72-0aa641f032a3",
   "metadata": {},
   "source": [
    "## Color picker"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "8d354b46-707d-4b67-add3-04c1e906ce31",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "96d92be0-66d1-4b09-9d13-ef120354841a",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "colorPicker <- mkColorPicker\n",
    "setField @Concise colorPicker False\n",
    "setField @Description colorPicker \"Pick a color\"\n",
    "setField @StringValue colorPicker \"Blue\"\n",
    "setField @Disabled colorPicker False\n",
    "colorPicker"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73b26165-d9a4-407a-81c7-1842675e27fc",
   "metadata": {},
   "source": [
    "## Controller\n",
    "The `Controller` allows a game controller to be used as an input device"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "5b204580-a4ab-4b48-b34e-2bcb5abae9ad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "97cbe9db-15a8-4be6-8660-1adf47d0d544",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "controller <- mkController\n",
    "setField @Index controller 0\n",
    "controller"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cd0edb8-9a47-4bc4-8ffc-a61e12fe66b5",
   "metadata": {},
   "source": [
    "## Container and Layout widgets\n",
    "\n",
    "These widgets are used to hold other widgets, called children. They can display multiple widgets or change its CSS styling.\n",
    "\n",
    "### Box"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "262e9246-0ce1-43dc-9ec8-a5b621957355",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a5529dc4-1eb2-47e7-b0c9-70a547288112",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "labels <- flip mapM [1..4] $ \\i->do\n",
    "    l <- mkLabel\n",
    "    setField @StringValue l $ pack $ (\"Label #\" ++ show i)\n",
    "    return $ ChildWidget l\n",
    "\n",
    "box <- mkBox\n",
    "setField @Children box labels\n",
    "box"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1749af43-63b1-4ee7-aed5-db5a8667c473",
   "metadata": {},
   "source": [
    "### HBox"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "db37b5ce-3154-4194-8241-a2b15e41fdcf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7c56564e-74f5-4bef-be16-02a9e31f9845",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "hbox <- mkHBox\n",
    "setField @Children hbox labels\n",
    "hbox"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6db2f1e2-dba0-42cc-8bf7-c883e0fdb939",
   "metadata": {},
   "source": [
    "### VBox"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "97500421-d638-4123-88c0-0fda9cd307b2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a733b6f5-5b13-43ac-bf0e-574c067028c1",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "vbox <- mkVBox\n",
    "setField @Children vbox labels\n",
    "vbox"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22e85f1a-8f07-443b-bd99-f17f52e78ea3",
   "metadata": {},
   "source": [
    "### GridBox\n",
    "\n",
    "This box uses the HTML Grid specification to create a two-dimensional grid. To set its grid values, we need to create a layout widget. Let's do a 3x3 grid:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "5a922615-b529-41ef-9af3-346b909f18bb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "2b5cc805-fa7f-4b54-ad73-99bb30091fbd",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "labels <- flip mapM [1..8] $ \\i->do\n",
    "    l <- mkLabel\n",
    "    setField @StringValue l $ pack $ (\"Label #\" ++ show i)\n",
    "    return $ ChildWidget l\n",
    "    \n",
    "layout <- mkLayout\n",
    "setField @L.GridTemplateColumns layout $ Just \"repeat(3, 10em)\"\n",
    "    \n",
    "gridBox <- mkGridBox\n",
    "setField @Children gridBox labels\n",
    "setField @W.Layout gridBox layout\n",
    "gridBox"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "269dcfce-ff9d-4c7a-85d1-6814dc813fd3",
   "metadata": {},
   "source": [
    "### Accordion\n",
    "\n",
    "Unlike the other container widgets, `Accordion` and `Tab` update their `selected_index` attribute when a tab or accordion element is selected. You can see what the user is doing, or set what the user is seeing.\n",
    "\n",
    "You can set `selected_index` to `Nothing` to close all accordions or deselect all tabs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "6e0c7074-d20a-44ae-8ea9-ee7aeacf6f27",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "611adc68-e5f8-4371-9ebf-57e2bef27f5c",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "accordion <- mkAccordion\n",
    "slider <- mkIntSlider\n",
    "text <- mkText\n",
    "setField @Children accordion [ChildWidget slider, ChildWidget text]\n",
    "setField @Titles accordion [\"Slider\", \"Text\"]\n",
    "accordion"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0701634d-d2be-451b-9bab-8826b0c90213",
   "metadata": {},
   "source": [
    "### Tabs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "f006c848-a5bb-4956-98c9-d68ec87ff703",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "6f1e0606-dc7a-4c2d-93d9-bcf58242219f",
       "version_major": 2,
       "version_minor": 0
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "tabs <- mkTab\n",
    "\n",
    "texts <- flip mapM [0..5] $ \\i->do\n",
    "    t <- mkText\n",
    "    setField @StringValue t $ pack $ (\"P\" ++ show i)\n",
    "    return $ ChildWidget t\n",
    "\n",
    "setField @Children tabs texts\n",
    "setField @Titles tabs [pack $ show i | i <- [0..5]]\n",
    "setField @SelectedIndex tabs $ Just 2\n",
    "tabs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aee75c09-81c5-46a5-a604-f2381485b4ec",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Haskell",
   "language": "haskell",
   "name": "haskell"
  },
  "language_info": {
   "codemirror_mode": "ihaskell",
   "file_extension": ".hs",
   "mimetype": "text/x-haskell",
   "name": "haskell",
   "pygments_lexer": "Haskell",
   "version": "9.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
